﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AsyncWinForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btn_Async_Click(object sender, EventArgs e)
        {
            // Action <string> act = DoSomething;

            // AsyncCallback a = t => 
            // {
            //     Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            // };
            //IAsyncResult iresult =  act.BeginInvoke("", a, null);
            // iresult.AsyncWaitHandle.WaitOne();
            // Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "结束");
            Stopwatch s1 = new Stopwatch();
            s1.Start();
            Func<string, int> func1 = (s) =>
            {
                Thread.Sleep(2000);
                Console.WriteLine(getThreadIdAndTime(s));
                return DateTime.Now.Year;
            };
            Func<string, int> func2 = (s) =>
            {
                Thread.Sleep(2000);
                Console.WriteLine(getThreadIdAndTime(s));
                return DateTime.Now.Year;
            };


            IAsyncResult r1 = func1.BeginInvoke("wing", null, null);
            IAsyncResult r2 = func2.BeginInvoke("lian", null, null);

            int resut = func1.EndInvoke(r1) + func2.EndInvoke(r2);
            Console.WriteLine(resut);
            s1.Stop();
            Console.WriteLine(s1.Elapsed);
            Console.WriteLine(getThreadIdAndTime("Main"));
        }

        string getThreadIdAndTime(string @object)
        {
            return @object + " threadId:" + Thread.CurrentThread.ManagedThreadId + " time:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
        }
        void DoSomething(string name)
        {
            Console.WriteLine(getThreadIdAndTime(name + "_start"));
            Thread.Sleep(2000);
            Console.WriteLine(getThreadIdAndTime(name + "_end"));

        }
        void callback(IAsyncResult ar)
        {

        }

        private void btn_ThreadPool_Click(object sender, EventArgs e)
        {

            //Console.WriteLine(getThreadIdAndTime( "main start"));
            //ManualResetEvent mre = new ManualResetEvent(false); //信号量初始化关闭
            //ThreadPool.QueueUserWorkItem(t =>
            //{
            //    Thread.Sleep(10000);
            //    Console.WriteLine(getThreadIdAndTime(t.ToString()));
            //    mre.Set(); // 信号量打开
            //}, "wing");
            //Console.WriteLine(getThreadIdAndTime("mian end"));
            //mre.WaitOne();
            //mre.Reset();//信号量关闭

            #region threadpool set
            int worker, io;
            ThreadPool.GetMaxThreads(out worker, out io); //最大线程数
            Console.WriteLine(worker + " io" + io);
            ThreadPool.GetMinThreads(out worker, out io); //最小线程数
            Console.WriteLine(worker + " io" + io);

            ThreadPool.GetAvailableThreads(out worker, out io); //可以用线程数
            Console.WriteLine(worker + " io" + io);

            ThreadPool.SetMaxThreads(18, 18); //设置最大线程数量
            ThreadPool.SetMinThreads(8, 8);


            #endregion
        }


        /// <summary>
        /// task waitall ,waitany ,continueWhenAny ,continueWhenAll
        /// parallel
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTask_Click(object sender, EventArgs e)
        {
            Console.Clear();
            Console.WriteLine(getThreadIdAndTime("main start"));
            List<Task> taskList = new List<Task>();
            for (int i = 0; i < 5; i++)
            {
                string name = "btnTask_Click" + i;
                Task task = Task.Factory.StartNew(() => { DoSomething(name); });
                //task.ContinueWith()
                taskList.Add(task);
            }
            Console.WriteLine("wait before");
            //Task.WaitAll(taskList.ToArray());
            //Task.WaitAny(taskList.ToArray());
            Task.Factory.ContinueWhenAll(taskList.ToArray(), tlist => { Console.WriteLine(getThreadIdAndTime("continue when all")); });
            Task.Factory.ContinueWhenAny(taskList.ToArray(), tlist => { Console.WriteLine(getThreadIdAndTime("continue when any")); });

            Console.WriteLine("wait after");

            Console.WriteLine(getThreadIdAndTime("main end"));
        }

        private void btnParallel_Click(object sender, EventArgs e)
        {
            Console.Clear();
            Console.WriteLine(getThreadIdAndTime("main start"));
            List<Action> actionList = new List<Action>();
            for (int i = 0; i < 9; i++)
            {
                actionList.Add(() => DoSomething("btnParallel_Click_" + i));
            }
            //Parallel.Invoke(actionList.ToArray());

            new Action(() =>
            {
                Console.WriteLine(getThreadIdAndTime("action"));
                ParallelOptions option = new ParallelOptions()
                {
                    MaxDegreeOfParallelism = 10
                };
                Parallel.For(1, 9, option, t => DoSomething("abc" + t));
            }).BeginInvoke(null, null);
            Console.WriteLine(getThreadIdAndTime("main end"));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            //System.Collections.Concurrent 线程安全的

        }

        public delegate void abc(object sender, EventArgs e);
        public abc ab;
        public event abc aa;
        private void button2_Click(object sender, EventArgs e)
        {
            abc a = button1_Click;
            a += btnParallel_Click;
            a(sender, e);

            aa = button1_Click;
            aa += button1_Click;
            aa(sender, e);
        }

        public void invoke()
        {
            aa.Invoke(null, null);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("");

            List<Guid> list = new List<Guid>();
            for (int i = 0; i <  1000; i++)
            {
                //sb.Append("Union   Select ID =  "+i+", UID = cast ('"+ Abp.SequentialGuidGenerator.Instance.Create(Abp.SequentialGuidGenerator.SequentialGuidDatabaseType.SqlServer).ToString() + "' as uniqueidentifier) \r\n");
                sb.Append("Union   Select ID =  "+i+", UID = cast ('"+ GuidExtension.NewSequentialGuid() + "' as uniqueidentifier) \r\n");
                
            }
            
        }


    }


}


namespace MyNamespace
{
    public partial class Form1
    {
        public Form1()
        {
            AsyncWinForm.Form1 f1 = new AsyncWinForm.Form1();
            f1.aa += button1_Click;
            f1.invoke();


            f1.ab += button1_Click;
            f1.ab.Invoke(null,null);
        }

        private void button1_Click(object sender, EventArgs e)
        {
             

        }
    }
}
